/**
 * Copyright (c) 2006-2013 Las Venturas Mineground
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */

package org.mineground.events;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;

/**
 * A reference to an event listener stores a weak reference to an instance of the object on which
 * the listener is defined. We use a weak reference because we don't want to influence the lifetime
 * of the object itself (as we won't own it). For performance reasons, we'll also store the priority
 * of the listener itself, so we can keep the SortedMap sorted.
 */
class EventListenerReference implements Comparable<EventListenerReference> {
    public WeakReference<Object> mObjectReference;
    public Method mListener;
    public EventPriority mPriority;

    /**
     * Initializes a new EventListenerReference. Only the EventDispatcher should do this.
     * 
     * @param object Instance of the class which holds this listener.
     * @param listener The listener itself, which will be invoked with the instance as specified.
     * @param priority Priority with which the listener will be invoked.
     */
    public EventListenerReference(Object object, Method listener, EventPriority priority) {
        this.mObjectReference = new WeakReference<Object>(object);
        this.mListener = listener;
        this.mPriority = priority;
    }
    
    /**
     * Compares this reference to another. If the two references are equal, the sorted set will skip
     * registering it and we'll only use the one that already exists. Otherwise, they will be sorted
     * based on the priority of the event.
     * 
     * @param other The Event Listener Reference we should compare against.
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(EventListenerReference other) {
        if (mObjectReference == other.mObjectReference && mListener == other.mListener)
            return 0;
        
        return this.mPriority.numericPriority() > other.mPriority.numericPriority() ? 1 : -1;
    }
}